home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / picklst.exe / DIALOGS1.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-07-26  |  12.7 KB  |  472 lines

  1. unit Dialogs1;
  2.  
  3. {************************************************}
  4. {                                                }
  5. {   Turbo Pascal 6.0                             }
  6. {   Turbo Vision Unit - Dialogs1                 }
  7. {                                                }
  8. {   Containing:                                  }
  9. {   tSelectItem, tSelectCollection,              }
  10. {   tPickList, tPickDialog                       }
  11. {   tTextDialog                                  }
  12. {                                                }
  13. {************************************************}
  14. {********************************}
  15. {***Programmed by             ***}
  16. {***Blake Watson              ***}
  17. {***CIS number 70303,373      ***}
  18. {********************************}
  19. interface
  20.  
  21. uses Objects, Drivers, Dialogs, Views, MsgBox, App,
  22.      Objects1;
  23.  
  24. const
  25.    MaxRows = 21;
  26.  
  27. type
  28.    pSelectItem = ^tSelectItem;
  29.    tSelectItem = object(tObject)
  30.       Name    : pString;
  31.       Selected: boolean;
  32.       constructor Init(S:String);
  33.       destructor Done; virtual;
  34.       end;
  35.  
  36.    pSelectCollection = ^tSelectCollection;
  37.    tSelectCollection = object(tCollection)
  38.       Pick: byte;
  39.       constructor Init(S:string);
  40.       function NameAt(I:Integer): string;
  41.       procedure NewItem(S:String); virtual;
  42.       function Selected(I:Integer): boolean;
  43.       procedure ToggleAt(I:Integer);
  44.       procedure DropNotSelected;
  45.       function LastSelectedItem: integer;
  46.       function NumberSelected: integer;
  47.       end;
  48.  
  49.    pPickList = ^tPickList;
  50.    tPickList = object(tView)
  51.       List  : PSelectCollection;
  52.       MaxItemLength, Picked, Highlight, NumRows,
  53.       NumCols: integer;
  54.       constructor Init(r: tRect; MIL, NC, NR: integer; AList: pSelectCollection);
  55.       procedure Draw; virtual;
  56.       procedure Choose(AnItem: Integer); virtual;
  57.       procedure HandleEvent(var Event:tEvent); virtual;
  58.       end;
  59.  
  60.    pPickDialog = ^tPickDialog;
  61.    tPickDialog = object(tDialog)
  62.       constructor Init(AList: pointer; X,Y: Integer);
  63.       procedure GetDims(var r: tRect; var W, Columns, rows: integer; Alist: pSelectCollection);
  64.       end;
  65.  
  66.    {tPickDialog is the first "useful" object.  Pass a tRect, a width, number of
  67.     columns and rows, and a TSelectCollection, and it will allow the user to
  68.     select up to <pick> items, marking the <selected> field of those items.}
  69.  
  70.    pTextDialog = ^tTextDialog;
  71.    tTextDialog = object(tPickDialog)
  72.       IsValid : boolean;
  73.       List    : pSelectCOllection;
  74.       constructor Init(var AList: pointer; X,Y: Integer; fn: string; name: string);
  75.       function LoadList(var fn, name, h: string; var temp: pCollection): boolean;
  76.       procedure InitList(h:string; t:pCollection); virtual;
  77.       function Valid(Command: Word): Boolean; virtual;
  78.       destructor Done; virtual;
  79.       end;
  80.  
  81.    {tTextDialog is a little more complex.  You pass an empty TSelectCollection,
  82.     the coords for where the list should appear, and it figures out how large
  83.     the dialog has to be.  The TSelectCollection is built from a list (spec'ed
  84.     by <name>) in a text file <fn>.
  85.  
  86.     The text file may have many lists in it, and follows this format:
  87.  
  88.     NumberOfItems,ListName,NumberToPick
  89.     Item
  90.     Item
  91.     ....
  92.     NumberOfItems,ListName,NumberToPick
  93.     ....
  94.  
  95.     tTextDialog returns ONLY the items that have been selected.}
  96.  
  97. function GetElement(S:String; N:byte): string;
  98. function GetNumericElement(S:String; N:byte): longint;
  99.  
  100. implementation
  101.  
  102. function GetElement(S:String; N:byte): string;
  103. var I,J,K: byte;
  104. begin
  105.    I := 1; J := 0;
  106.    while(pos(',',S)>0) and (I<>N) do
  107.    begin
  108.       J := pos(',',s);
  109.       inc(I);
  110.       s[j] := ' ';
  111.       end;
  112.    If I<>N then GetElement := ''
  113.    else begin
  114.       inc(J);
  115.       K := pos(',',S);
  116.       If K = 0 then K := Length(S) + 1;
  117.       GetElement := copy(S,J,K-J);
  118.       end;
  119.    end;
  120.  
  121. function GetNumericElement(S:String; N:byte): longint;
  122. var l:longint; code:integer;
  123. begin
  124.    s := GetElement(S,N);
  125.    val(s,l,code);
  126.    GetNumericElement := l;
  127.    end;
  128.  
  129. {tSelectItem}
  130.  
  131. constructor tSelectItem.Init(S:String);
  132. var w: byte;
  133. begin
  134.    tObject.Init;
  135.    w := pos('  ',s);
  136.    if w = 0 then w := length(S);
  137.    Name := newStr(copy(S,1,w));
  138.    selected := false;
  139.    end;
  140.  
  141. destructor tSelectItem.Done;
  142. begin
  143.    DisposeStr(Name);
  144.    end;
  145.  
  146. {tSelectCollection}
  147.  
  148. constructor tSelectCollection.Init(S:String);
  149. begin
  150.    tCollection.Init(GetNumericElement(s,1),0);
  151.    Pick := GetNumericElement(s,3);
  152.    If Pick = 0 then Pick := 1;
  153.    end;
  154.  
  155. function tSelectCollection.NameAt(I: Integer): string;
  156. begin
  157.    NameAt := tSelectItem(At(I)^).Name^;
  158.    end;
  159.  
  160. function tSelectCollection.Selected(I: Integer): boolean;
  161. begin
  162.    Selected := tSelectItem(At(I)^).Selected;
  163.    end;
  164.  
  165. procedure tSelectCollection.ToggleAt(I: Integer);
  166. begin
  167.    tSelectItem(At(I)^).Selected := not tSelectItem(At(I)^).Selected;
  168.    end;
  169.  
  170. procedure tSelectCollection.DropNotSelected;
  171. var I: Integer;
  172. begin
  173.    for I := Count-1 downto 0 do
  174.       if not tSelectItem(At(I)^).Selected
  175.          then Free(At(I));
  176.    end;
  177.  
  178. procedure tSelectCollection.NewItem(S:string);
  179. begin
  180.    Insert(New(pSelectItem, init(S)));
  181.    end;
  182.  
  183. function tSelectCollection.LastSelectedItem: integer;
  184. var I: integer;
  185. begin
  186.    I := Count;
  187.    repeat dec(i) until (I=0) or Selected(I);
  188.    LastSelectedItem := I;
  189.    end;
  190.  
  191. function tSelectCollection.NumberSelected: integer;
  192. var I, J: integer;
  193. begin
  194.    J := 0;
  195.    for I := 0 to Count -1 do
  196.        if Selected(I) then inc(J);
  197.    NumberSelected := J;
  198.    end;
  199.  
  200.  
  201. {tPICKLIST}
  202.  
  203. constructor tPickList.Init;
  204. var I : integer;
  205.     p : pointer;
  206. begin
  207.    tview.init(R);
  208.    EventMask := EventMask or evMouseMove;
  209.    Options := ofSelectable or ofTopSelect or ofPreProcess or ofCentered;
  210.  
  211.    List := AList;
  212.    MaxItemLength := MIL;
  213.    NumCols := NC;
  214.    NumRows := NR;
  215.    picked := 0;
  216.    for I := 0 to List^.Count -1 do
  217.       if List^.Selected(I) then inc(picked);
  218.  
  219.    end;
  220.  
  221. procedure tPickList.Draw;
  222. var I, X, Y : byte;
  223.     s       : string;
  224. begin
  225.    X := 0; Y := 0;
  226.    for I := 0 to List^.Count-1 do
  227.    begin
  228.       If Y + 1 > NumRows then
  229.       begin
  230.          Y := 0;
  231.          Inc(X, MaxItemLength);
  232.          end;
  233.                            {This code guarantees that s fills all space}
  234.       S := List^.NameAt(I);
  235.       while(Length(S)<MaxItemLength) do s := S + ' ';
  236.  
  237.       if I = Highlight then writeStr(X, Y, s, 11)
  238.       else if List^.Selected(I) then writeStr(X,Y,S,3)
  239.       else writeStr(x,y,S,1);
  240.       Inc(y);
  241.       end;
  242.  
  243.    S := '';
  244.    while(Length(S)<MaxItemLength) do s := S + ' ';
  245.    while(Y<=NumRows) do
  246.    begin
  247.       writestr(X,Y,S,1);
  248.       inc(y);
  249.       end;
  250.  
  251.    end;
  252.  
  253. procedure tPickList.Choose(AnItem: Integer);
  254. begin
  255.    If tSelectItem(List^.At(AnItem)^).Selected then dec(picked)
  256.    else inc(picked);
  257.    tSelectItem(List^.At(AnItem)^).Selected :=
  258.       not tSelectItem(List^.At(AnItem)^).Selected;
  259.    end;
  260.  
  261. procedure tPickList.HandleEvent;
  262. var CoOrds: TPoint;
  263.     OH,I,J: integer;
  264.     r     : tRect;
  265.     P     : Pview;
  266.     s     : string;
  267. begin
  268.    tView.HandleEvent(Event);
  269.    If Event.What and (evBroadCast or evCommand) = 0 then
  270.    begin
  271.       Oh := Highlight;
  272.       if (event.What and evKeyboard <> 0) then
  273.       begin
  274.          case event.KeyCode of
  275.             kbDown : Inc(Highlight);
  276.             kbUp   : Dec(Highlight);
  277.             kbRight: if numcols>1 then inc(Highlight,NumRows);
  278.             kbLeft : if numcols>1 then dec(Highlight,NumRows);
  279.             else
  280.                if Event.CharCode in [' ',#13] then
  281.                begin
  282.                  If (Event.charCode = ' ') or not List^.Selected(Highlight)
  283.                  then Choose(Highlight);
  284.                  if Event.CharCode = #13 then picked := List^.pick;
  285.                  end
  286.             else begin
  287.                I := Highlight; J := 0;
  288.                repeat
  289.                   inc(I); Inc(J);
  290.                   If I = List^.Count then I := 0;
  291.                   If I < List^.Count then S := List^.NameAt(I);
  292.                   until(Upcase(Event.CharCode)=s[1]) or (List^.Count=J);
  293.                If J<=List^.Count then
  294.                begin
  295.                   highlight := I;
  296.                   choose(Highlight);
  297.                   end;
  298.                end;
  299.             end;
  300.          If Highlight = -1 then highlight := List^.Count-1
  301.          else If Highlight < -1 then Highlight := 0
  302.          else if Highlight = List^.Count then Highlight := 0
  303.          else if Highlight > List^.Count then Highlight := List^.Count-1;
  304.          end
  305.       else if (event.What and evMouse <> 0) and MouseInView(Event.Where) then
  306.       begin
  307.          MakeLocal(Event.Where,CoOrds);
  308.          Highlight := CoOrds.Y;
  309.          If (NumCols > 0) and (CoOrds.x + 1> MaxItemLength) then
  310.          while Coords.x + 1> MaxItemLength do
  311.          begin
  312.             dec(coords.x, MaxItemLength);
  313.             Inc(highLight, NumRows);
  314.             end;
  315.          If Highlight >= List^.Count then Highlight := List^.Count-1;
  316.          if (Event.What and evMouseDown <> 0) then
  317.          begin
  318.             If (Event.Buttons = mbLeftButton) or not List^.Selected(Highlight)
  319.                then Choose(Highlight);
  320.             if Event.Buttons = mbRightButton then Picked := List^.Pick;
  321.             end;
  322.          end;
  323.       If Event.CharCode<>#27 then ClearEvent(Event);
  324.       If Picked = List^.Pick then p := Message(Owner, evCommand, cmOK, nil)
  325.       else If OH<>Highlight then DrawView;
  326.       end;
  327.    end;
  328.  
  329. {tPickDialog}
  330.  
  331. constructor tPickDialog.Init;
  332. var Int: pPickList;
  333.     Rows, W, Columns, TotalWidth
  334.      : Integer;
  335.     r: tRect;
  336. begin
  337.    GetDims(r, W, Columns, rows, Alist);
  338.  
  339.    r.a.x := X; r.a.y := y;
  340.    inc(r.b.x,x); inc(r.b.y,y);
  341.  
  342.    while r.b.x >= ScreenWidth do r.Move(-1,0);
  343.    while r.b.y >= ScreenHeight do r.Move(0, -1);
  344.  
  345.    tDialog.Init(r,'');
  346.    state := state and not sfShadow;
  347.    r.grow(-1, -1);;
  348.    Insert(New(pPickList, Init(r, W, columns, rows, Alist)));
  349.    end;
  350.  
  351. procedure tPickDialog.GetDims;
  352. var TotalWidth,
  353.     I: byte;
  354. begin
  355.    w := 0; Columns := 1; Rows := AList^.Count;
  356.  
  357.    for I := 0 to Rows-1 do
  358.       if Length(AList^.NameAt(I)) > w then
  359.          w := length(AList^.NameAt(I));
  360.    I := Rows;
  361.    Inc(W);
  362.    TotalWidth := W;
  363.    while I> MaxRows do
  364.    begin
  365.       Inc(Columns);
  366.       Inc(TotalWidth,W);
  367.       I := (Rows div Columns);
  368.       If Rows mod columns <> 0 then inc(I);
  369.       end;
  370.    Rows := I;
  371.    If TotalWidth < 14 then TotalWidth := 14;
  372.    while W*Columns < 14 do inc(w); 
  373.  
  374.    r.assign(0,0,totalwidth+2, rows+2);
  375.    end;
  376.  
  377. {tTextDialog}
  378.  
  379. constructor tTextDialog.init;
  380. var h: string;
  381.     temp   : pCollection;
  382. begin
  383.     IsValid := false;
  384.     If LoadList(fn, name,h, temp) then
  385.     begin
  386.       InitList(H, Temp);
  387.       dispose(temp, done);
  388.       AList := list;
  389.       tPickDialog.Init(List,X,Y);   (*list gets zeroed out here*)
  390.       list := AList;
  391.       IsValid := true;
  392.       end;
  393.    end;
  394.  
  395. function tTextDialog.LoadList(var fn, name, h: string; var Temp: pCollection): boolean;
  396. var f   : text;
  397.     w   : word;
  398.     NumToPick,
  399.     n, I   : integer;
  400.     s, t   : string;
  401. begin
  402.    LoadList := false;
  403.    assign(f,fn);
  404.    {$I-}
  405.    reset(F);
  406.    {$I+}
  407.    If IoResult<>0 then begin
  408.       w := MessageBox('Unable to open file '+fn+'.',nil,mfError+mfCancelButton);
  409.       done;
  410.       end
  411.    else begin
  412.       readln(f,s);
  413.       n := getNumericElement(s,1);
  414.       t := getElement(s,2);
  415.       while(t<>name) and not eof(F) do
  416.       begin
  417.          for i := 1 to n do readln(f,s);
  418.          readln(f,s);
  419.          t := getElement(s,2);
  420.          n := getNumericElement(s,1);
  421.          end;
  422.       if t<>name then begin
  423.          w := MessageBox('Unable to find list '+name+'.',nil,mfError+mfCancelButton);
  424.          n := 0;
  425.          done;
  426.          end
  427.       else if n = 0 then begin
  428.          w := MessageBox('No pick number in list '+name+'.',nil,mfError+mfCancelButton);
  429.          done;
  430.          end
  431.       else begin
  432.          h := s;
  433.          temp := new(pCollection, init(n,0));
  434.          for I := 1 to Temp^.Limit do
  435.          begin
  436.             readln(f,s);
  437.             Temp^.Insert(New(pStrObj, Init(S)));
  438.             end;
  439.          system.close(f);
  440.          LoadList := true;
  441.          end;
  442.       end;
  443.    end;
  444.  
  445.  
  446. function tTextDialog.Valid(Command: Word): Boolean;
  447. begin
  448.    If (Command = 0) and not IsValid then Valid := False
  449.    else Valid := true;
  450.    end;
  451.  
  452. procedure tTextDialog.InitList(h:string; t:pCollection);
  453. var p: pSelectCollection;
  454.     i: integer;
  455. begin
  456.    p := New(pSelectCollection, init(H));
  457.    for I := 0 to t^.Limit-1 do
  458.       p^.NewItem(tStrObj(t^.at(i)^).p^);
  459.    List := P;
  460.    end;
  461.  
  462. destructor tTextDialog.done;
  463. begin
  464.    List^.DropNotSelected;
  465.    IsValid := false;
  466.    tPickDialog.Done;
  467.    end;
  468.  
  469.    end.
  470.  
  471.  
  472.